from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
from time import sleep
from yt_dlp import YoutubeDL
from yt_dlp.utils import YoutubeDLError


async def searchsong(song=None):
    search_query = song.replace(' ', '+').lower()
    url = f'https://www.youtube.com/results?search_query={search_query}' 
    options = Options()
    options.add_argument('--headless')
    s = Service(executable_path='funcs/geckodriver')
    driver = webdriver.Firefox(options=options, service=s)
    driver.maximize_window()
    try:
        driver.get(url=url)
        sleep(1)
        uris = driver.find_elements(By.ID, 'video-title')
        ddd = []
        for i in uris:
            i = i.get_attribute('href')
            if i != None:
                ddd.append(i)
        return ddd[0]
    except Exception as ex:
        print(ex)
    finally:
        driver.close()
        driver.quit()


def download_audio(youl, pathik):
    options: dict = {
        "format": "m4a/bestaudio/best",
        "ffmpeg_location": '/usr/bin/ffmpeg',
        "geo_bypass": True,
        "noplaylist": True,
        "noprogress": True,
        "postprocessors": [
            {
                "key": "FFmpegExtractAudio",
                "preferredcodec": "mp3",
                "preferredquality": "160",
            }
        ],
        "quiet": True,
    }
    ydl: YoutubeDL = YoutubeDL(params=options)
    try:
        video_info = ydl.extract_info(youl, download=False)
        duration: int | None = video_info.get("duration")
        if duration <= 900:
            path_to_file = f'{pathik}'
            ydl.params.update({"outtmpl": {"default": path_to_file}})
            ydl.download(youl)
            return f"{path_to_file}.mp3"
    except YoutubeDLError as ex:
        print(ex)
    return None

async def rundown(url, path):
    try:
        download_audio(youl=url, pathik=path)
        return True
    except Exception:
        return False
